"""
@Author  : 康帅
@Time    : 2021/2/4 17:12
@Function: itertools工具
"""


import itertools
from collections import Counter
from operator import itemgetter
from itertools import groupby


def itertools_tools():
    """
    迭代工具模块
    :return:
    """
    # 产生ABCD的全排列
    a = itertools.permutations('ABCD')
    # 产生ABCDE的五选三组合
    b = itertools.combinations('ABCDE', 3)
    # 产生ABCD和123的笛卡尔积
    c = itertools.product('ABCD', '123')
    # 产生ABC的无限循环序列
    d = itertools.cycle(('A', 'B', 'C'))
    print(a, b, c, d)


def itertools_group_by():
    """
    通过某个字段将记录分组
    :return:
    """
    rows = [
        {'address': '5412 N CLARK', 'date': '07/01/2012'},
        {'address': '5148 N CLARK', 'date': '07/04/2012'},
        {'address': '5800 E 58TH', 'date': '07/02/2012'},
        {'address': '2122 N CLARK', 'date': '07/03/2012'},
        {'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'},
        {'address': '1060 W ADDISON', 'date': '07/02/2012'},
        {'address': '4801 N BROADWAY', 'date': '07/01/2012'},
        {'address': '1039 W GRANVILLE', 'date': '07/04/2012'},
    ]

    # 首先按所需字段排序
    rows.sort(key=itemgetter('date'))
    # 分组迭代
    for date, items in groupby(rows, key=itemgetter('date')):
        print(date)
        for i in items:
            print(' ', i)


def collections_counter():
    """
    找出序列中出现次数最多的元素
    :return:
    """
    """
    namedtuple：命令元组，它是一个类工厂，接受类型的名称和属性列表来创建一个类。
    deque：双端队列，是列表的替代实现。Python中的列表底层是基于数组来实现的，而deque底层是双向链表，因此当你需要在头尾添加和删除元素是，deque会表现出更好的性能，渐近时间复杂度为$O(1)$。
    Counter：dict的子类，键是元素，值是元素的计数，它的most_common()方法可以帮助我们获取出现频率最高的元素。Counter和dict的继承关系我认为是值得商榷的，按照CARP原则，Counter跟dict的关系应该设计为关联关系更为合理。
    OrderedDict：dict的子类，它记录了键值对插入的顺序，看起来既有字典的行为，也有链表的行为。
    defaultdict：类似于字典类型，但是可以通过默认的工厂函数来获得键对应的默认值，相比字典中的setdefault()方法，这种做法更加高效
    """

    words = [
        'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',
        'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around',
        'the', 'eyes', "don't", 'look', 'around', 'the', 'eyes',
        'look', 'into', 'my', 'eyes', "you're", 'under'
    ]
    counter = Counter(words)
    print(counter.most_common(3))


if __name__ == '__main__':
    itertools_tools()
    collections_counter()
    itertools_group_by()
